package com.xlz.timer;

import java.text.ParseException;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xlz.domain.AppWorker;
import com.xlz.domain.AppTask;
import com.xlz.manager.DefaultDstManager;
import com.xlz.util.Common;
import com.xlz.util.CronExpression;
import com.xlz.worker.Worker;
import com.xlz.worker.WorkerBeanFactory;

/**
 * 调度执行task
 * @author 张蕾蕾
 * @date 2018 03 24
 */
public class WorkerTask extends TimerTask {
	
	protected final Logger LOG = LoggerFactory.getLogger(getClass());
	
	private Worker worker;
	private Timer timer;
	private DefaultDstManager scheduleManager;
	
	public WorkerTask(Worker worker,Timer timer,DefaultDstManager scheduleManager){
		this.worker = worker;
		this.timer = timer;
		this.scheduleManager = scheduleManager;
	}
	
	public Worker init(AppWorker appWorker,AppTask appTask)throws Exception{
		try {
			if(Common.RUNNTIME_CONTAINER_SPRING.equals(scheduleManager.getContainer())){
				worker = WorkerBeanFactory.newWorker(appTask.getDealBean());
			}else{
				worker = newInstance(appTask);
			}
			//设置task初始参数
			worker.setAppTask(appTask);
			worker.setThreadPoolSize(appTask.getSingleTaskThreadCount());
			String jobItems[] = appTask.getShardItem().split("\\|");
			worker.setScheduleManager(scheduleManager);
			worker.setShardItemCount(jobItems.length);
			//初始化
			worker.init();
			
			setSchedule(appTask);
			worker.setShardItems(appWorker.getShardItem());
			return worker;
		} catch (ParseException e) {
			LOG.error("初始化调度任务异常，当前任务{}：",appTask,e);
			throw e;
		}
	}
	
	private Worker newInstance(AppTask appTask)throws Exception{
		try {
			Class<?> cls = Class.forName(appTask.getDealBean()); // 取得Class对象
			Worker obj = (Worker)cls.newInstance();
			return obj;
		} catch (Exception e) {
			LOG.error("初始化调度任务异常，当前任务{}：",appTask,e);
			throw e;
		} 
	}
	
	public long getCurrentSystemTime(){
		return System.currentTimeMillis();
	}
	
	@Override
	public void run() {
		try {
			//Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
			this.cancel();// 取消调度任务
			if (worker.getAppTask().getReadiness() == 1) {
				//TODO 判断当前时间如果在高级列表中则不执行
				if (true) {
					worker.doSelect();
				}
				setSchedule(worker.getAppTask());
			}else{
				this.scheduleManager.stopSingleTaskJobs(worker.getAppTask());
			}
		} catch (Exception e) {
			if(!(e instanceof IllegalStateException))
				LOG.error("加入worker的调度异常{}",worker.getAppTask(), e);
			this.scheduleManager.stopSingleTaskJobs(worker.getAppTask());
		}
	}
	
	private void setSchedule(AppTask appTask) throws ParseException{
		if(appTask.getReadiness().intValue() == 1){
			long ce = toLong(appTask.getCronExpression());
			if(ce != -1 && timer != null){
				timer.schedule(new WorkerTask(worker,timer,scheduleManager),ce);
			}else{
				CronExpression cexpStart = new CronExpression(appTask.getCronExpression());
				Date current = new Date( getCurrentSystemTime());
				Date nextStartTime = cexpStart.getNextValidTimeAfter(current);
				if(timer != null){
					timer.schedule(new WorkerTask(worker,timer,scheduleManager),nextStartTime);
				}
			}
		}else{
			this.scheduleManager.stopSingleTaskJobs(worker.getAppTask());
		}
	}
	
	private long toLong(String number){
		try {
			return Long.valueOf(number);
		} catch (NumberFormatException e) {
			return -1l;
		}
	}
}
